package miniBanco.Handler;


import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.JOptionPane;
import miniBanco.Core.*;
import miniBanco.Dto.ClienteDTO;
import miniBanco.Dto.CuentaDTO;
import miniBanco.Dto.Mapper.DTOMapper;
import miniBanco.Exceptions.HandledException;
import miniBanco.Gui.*;
import miniBanco.Mapper.MapperRegistry;
import miniBanco.Mapper.Interface.IClienteFinder;
import miniBanco.Mapper.Interface.ICuentaFinder;
import basics.DBManager;


public class HandlerClientes   {
	Component lastComponent = null;
	//private static HandlerClientes instance = null;
	ICuentaFinder cuentaFinder;
	IClienteFinder clienteFinder;
	ArrayList<Cliente> clienteList;
	Cliente cliente;
	//Componentes
	private ClientesGridAbm clientesGridAbm;
	private CuentasGridAbm cuentasGridAbm;
	private HandlerUsuariosMainFrame mainHandler;
	public HandlerClientes(HandlerUsuariosMainFrame mainHandler) {
		this.mainHandler = mainHandler;
		clienteFinder = MapperRegistry.GetInstance().ClienteMapper();
		cuentaFinder = MapperRegistry.GetInstance().CuentaMapper();
		clientesGridAbm = new ClientesGridAbm();
		cuentasGridAbm = new CuentasGridAbm();
	}

	private void OpenCuentasFrame(ClienteDTO cliDTO)
	{
		long idCliente = cliDTO.getId();
		
		cliente = null;
		for(Cliente c:clienteList)
		{
			if(c.getID() == idCliente)
			{
				cliente = c;
			}
		}
		if(cliente == null)
			return;
		

		RefrescarCuentasGrid(cliente);
		mainHandler.AgregarComponente(cuentasGridAbm);	
		
		cuentasGridAbm.getBtnVoler().addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				
				mainHandler.AgregarComponente(clientesGridAbm);			
			}
		});
		
		cuentasGridAbm.getGrid().getTopBar().buttonAlta.addActionListener(new ActionListener() {	
			@Override
			public void actionPerformed(ActionEvent arg0) {		
				CuentaDTO c = new CuentaDTO();
				c.setCliente(cliente.getNombre());
				c.setIdCliente(cliente.getID());
				
				OnOpenEditableCuentas(LocalRequestEnum.Insertar,c);
			}
		});
		cuentasGridAbm.getGrid().getTopBar().buttonModificacion.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				
				if(cuentasGridAbm.getGrid().getTable().getSelectedRow() == -1){
					JOptionPane.showMessageDialog(null, "Debe seleccionar al menos un registro");
					return;
				}
				int row = cuentasGridAbm.getGrid().getTable().getSelectedRow();
				CuentaDTO cuentaDTO = cuentasGridAbm.getData().get(row);
				OnOpenEditableCuentas(LocalRequestEnum.Modificar,cuentaDTO);
			}
		});
		
		cuentasGridAbm.getGrid().getTopBar().buttonBaja.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				if(cuentasGridAbm.getGrid().getTable().getSelectedRow() == -1)
				{
					JOptionPane.showMessageDialog(null, "Debe seleccionar al menos un registro");
					return;
				}
				int row = cuentasGridAbm.getGrid().getTable().getSelectedRow();
				CuentaDTO cuentaDTO = cuentasGridAbm.getData().get(row);
				OnOpenEditableCuentas(LocalRequestEnum.Borrar,cuentaDTO);
			}
		});	

	}
	
	private void RefrescarCuentasGrid(Cliente c)
	{
		ArrayList<Cuenta> cuentasList = (ArrayList<Cuenta>) c.getCuentas();
		ArrayList<CuentaDTO> cuentaDTOList = DTOMapper.ToCuentaDtoList(cuentasList);
		cuentasGridAbm.Refresh(cuentaDTOList);
		cuentasGridAbm.updateUI();
	}
	private void RefrescarClientesGrid()
	{
		 MapperRegistry.GetInstance().ClienteMapper().borrarLoadedMap();
		clienteList = clienteFinder.findAll();	
		ArrayList<ClienteDTO> data = DTOMapper.ToClienteDtoList(clienteList);
		clientesGridAbm.Refresh(data);
		clientesGridAbm.updateUI();
	}
	public void Show() {
		try
		{
			clientesGridAbm = new ClientesGridAbm();
			RefrescarClientesGrid();
			mainHandler.AgregarComponente(clientesGridAbm);
			//Handler de los botones
			clientesGridAbm.getGrid().getTopBar().buttonAlta.addActionListener(new ActionListener() {	
				@Override
				public void actionPerformed(ActionEvent arg0) {
					OnOpenEditable(LocalRequestEnum.Insertar,null);
				}
			});
			clientesGridAbm.getGrid().getTopBar().buttonModificacion.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(ActionEvent arg0) {
					
					if(clientesGridAbm.getGrid().getTable().getSelectedRow() == -1){
						JOptionPane.showMessageDialog(null, "Debe seleccionar al menos un registro");
						return;
					}
					int row = clientesGridAbm.getGrid().getTable().getSelectedRow();
					ClienteDTO cliDTO = clientesGridAbm.getData().get(row);
					OnOpenEditable(LocalRequestEnum.Modificar,cliDTO);
				}
			});
			
			clientesGridAbm.getGrid().getTopBar().buttonBaja.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent arg0) {
					if(clientesGridAbm.getGrid().getTable().getSelectedRow() == -1)
					{
						JOptionPane.showMessageDialog(null, "Debe seleccionar al menos un registro");
						return;
					}
					int row = clientesGridAbm.getGrid().getTable().getSelectedRow();
					ClienteDTO cliDTO = clientesGridAbm.getData().get(row);
					OnOpenEditable(LocalRequestEnum.Borrar,cliDTO);
				}
			});
			
			clientesGridAbm.getBtnVerCuentas().addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent arg0) {
					if(clientesGridAbm.getGrid().getTable().getSelectedRow() == -1)
					{
						JOptionPane.showMessageDialog(null, "Debe seleccionar al menos un registro");
						return;
					}
					int row = clientesGridAbm.getGrid().getTable().getSelectedRow();
					ClienteDTO cliDTO = clientesGridAbm.getData().get(row);
					OpenCuentasFrame(cliDTO);
				}
			});
       	}
		catch(HandledException ex)
		{
			JOptionPane.showMessageDialog(null, ex.getMessage());	
		}
		catch(Exception ex)
		{
			DBManager.Error(ex);
			JOptionPane.showMessageDialog(null, "Se produjo un error inesperado. Ver log de errores");
		}     	
	}

	public void OnOpenEditable(final LocalRequestEnum pLocalRequest,ClienteDTO row) {
		try 
    	{
			final ClientesForm frm = new ClientesForm();
	   		if(pLocalRequest != LocalRequestEnum.Insertar)
	   		{
	   			frm.setFormValues(row);
	   		}
	   		mainHandler.AgregarComponente(frm);
			frm.buttonBar.buttonOK.addActionListener(
					
	                new ActionListener() {
	                	private void borrar()
	                	{
	                		Cliente c = getFormValues();
	                		
	                		clienteFinder.doDelete(c);
	                	}
	                	private void save()
	                	{
	                		try
        					{
            					clienteFinder.doSave(getFormValues());
        					}
        					catch(HandledException ex)
        					{
        						JOptionPane.showMessageDialog(null, ex.getMessage());	
        					}
        					catch(Exception ex)
        					{
        						DBManager.Error(ex);
        						JOptionPane.showMessageDialog(null, "Se produjo un error inesperado. Ver log de errores");
        					}  
	                	}
	                	public Cliente getFormValues()
	                	{
        					ClienteDTO cliDto = frm.getFormValues();
        					Cliente cliente = DTOMapper.ToCliente(cliDto);
        					return cliente;
	                	}
	                    public void actionPerformed(ActionEvent e) {
	                    	switch(pLocalRequest)
	            			{
	            				case Insertar: save();break;
	            				case Modificar: save();break;
	            				case Borrar: borrar();break;
	            			}
	                    	OnABMCloseWindow(true);
	                    }
	                }
	            );
			
			frm.buttonBar.buttonCancel.addActionListener(
	                new ActionListener() {
	                    public void actionPerformed(ActionEvent e) {
	                    	OnABMCloseWindow(false);
	                    }
	                }
	            );
		} 
    	catch (Exception ex) 
    	{
    		DBManager.Error(ex);
    		JOptionPane.showMessageDialog(null, ex.getMessage());
    	}		
	}
	
	public void OnOpenEditableCuentas(final LocalRequestEnum pLocalRequest,final CuentaDTO row) {
		try 
    	{
			final CuentasForm frm = new CuentasForm();
		    frm.setFormValues(row);

	   		mainHandler.AgregarComponente(frm);
			frm.buttonBar.buttonOK.addActionListener(
					
	                new ActionListener() {
	                	private void borrar()
	                	{
	                		Cuenta c = getFormValues();
	                		c.setID(row.getId());
	                		cuentaFinder.doDelete(c);
	                	}
	                	private void save()
	                	{
	                		try
        					{
	                			Cuenta c = getFormValues();
	                			//if(pLocalRequest != LocalRequestEnum.Insertar)
	                			//	c.setID(row.getId());
	                			
	                			cliente.AgregarCuenta(c);
	                			clienteFinder.doSave(cliente);
        					}
        					catch(HandledException ex)
        					{
        						JOptionPane.showMessageDialog(null, ex.getMessage());	
        					}
        					catch(Exception ex)
        					{
        						DBManager.Error(ex);
        						JOptionPane.showMessageDialog(null, "Se produjo un error inesperado. Ver log de errores");
        					}  
	                	}
	                	public Cuenta getFormValues()
	                	{
	                		CuentaDTO cuentaDTO = frm.getFormValues();
        					Cuenta cuenta = DTOMapper.ToCuenta(cuentaDTO);
        					return cuenta;
	                	}
	                    public void actionPerformed(ActionEvent e) {
	                    	switch(pLocalRequest)
	            			{
	            				case Insertar: save();break;
	            				case Modificar: 
	            					JOptionPane.showMessageDialog(null, "No se puede modificar un cuenta. Solo Ver");
	            					;break;
	            				case Borrar: borrar();break;
	            			}
	                    	OnABMCuentasCloseWindow(true);
	                    }
	                }
	            );
			
			frm.buttonBar.buttonCancel.addActionListener(
	                new ActionListener() {
	                    public void actionPerformed(ActionEvent e) {
	                    	OnABMCloseWindow(false);
	                    }
	                }
	            );
		} 
    	catch (Exception ex) 
    	{
    		DBManager.Error(ex);
    		JOptionPane.showMessageDialog(null, ex.getMessage());
    	}		
	}	
	public void OnABMCuentasCloseWindow(boolean refresh) {
		if(refresh)
		{
			RefrescarCuentasGrid(cliente);
		}
		mainHandler.AgregarComponente(cuentasGridAbm);
	}
	public void OnABMCloseWindow(boolean refresh) {
		if(refresh)
		{
			RefrescarClientesGrid();
		}
		mainHandler.AgregarComponente(clientesGridAbm);
	}


}
